package com.idcloud.common.utils;

import org.json.JSONArray;
import org.json.JSONObject;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;

public class CommonUtil {

    /**
     * 获取当前日期时间
     *
     * @return 返回时间类型 yyyy-MM-dd HH:mm:ss
     */
    public static String getCurrentDateTime() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return df.format(new Date());
    }

    /**
     * 获取当前日期
     *
     * @return 返回时间类型 yyyy-MM-dd
     */
    public static String getCurrentDate() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        return df.format(new Date());
    }

    /**
     * 格式化日期
     *
     * @return 返回Date
     */
    public static Date formatDateTime(String datetime) throws ParseException {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return df.parse(datetime);
    }

    public static Date formatDate(String date) throws ParseException {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        return df.parse(date);
    }

    /**
     * 格式化日期
     *
     * @return 返回String
     */
    public static String formatDateTime(long datetime) throws ParseException {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return df.format(datetime);
    }

    public static String getCurrentFormatDateTime(String format) {
        SimpleDateFormat df = new SimpleDateFormat(format);
        return df.format(new Date());
    }

    /**
     * 获取UID
     *
     * @return 32位UUID
     */
    public static String getUID() {
        return getCurrentFormatDateTime("yyyyMMddHHmmssSSS") + UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 判断是否为空
     *
     * @return
     */
    public static boolean checkNull(String value) {
        if (value == null || value.equals("")) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 获取随机字符串
     *
     * @return
     */
    public static String getRandomString(int length) {
        String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(62);
            sb.append(str.charAt(number));
        }
        return sb.toString();
    }

    /**
     * 去重
     *
     * @return
     */
    public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        ConcurrentHashMap<Object, Boolean> map = new ConcurrentHashMap<>(16);
        return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

    /**
     * 实体类json化
     *
     * @return
     */
    public static int getType(Class<?> type) {
        if (type != null && (String.class.isAssignableFrom(type) || Character.class.isAssignableFrom(type) || Character.TYPE.isAssignableFrom(type) || char.class.isAssignableFrom(type)))
            return 0;
        if (type != null && (Byte.TYPE.isAssignableFrom(type) || Short.TYPE.isAssignableFrom(type) || Integer.TYPE.isAssignableFrom(type) || Integer.class.isAssignableFrom(type) || Number.class.isAssignableFrom(type) || int.class.isAssignableFrom(type) || byte.class.isAssignableFrom(type) || short.class.isAssignableFrom(type)))
            return 1;
        if (type != null && (Long.TYPE.isAssignableFrom(type) || long.class.isAssignableFrom(type)))
            return 2;
        if (type != null && (Float.TYPE.isAssignableFrom(type) || float.class.isAssignableFrom(type)))
            return 3;
        if (type != null && (Double.TYPE.isAssignableFrom(type) || double.class.isAssignableFrom(type)))
            return 4;
        if (type != null && (Boolean.TYPE.isAssignableFrom(type) || Boolean.class.isAssignableFrom(type) || boolean.class.isAssignableFrom(type)))
            return 5;
        if (type != null && type.isArray())
            return 6;
        if (type != null && Connection.class.isAssignableFrom(type))
            return 7;
        if (type != null && JSONArray.class.isAssignableFrom(type))
            return 8;
        if (type != null && List.class.isAssignableFrom(type))
            return 9;
        if (type != null && Map.class.isAssignableFrom(type))
            return 10;
        return 11;
    }

    public static JSONObject toJson(Object obj) {
        JSONObject json = new JSONObject();
        try {
            Field[] fields = obj.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                switch (getType(field.getType())) {
                    case 0:
                        json.put(field.getName(), (field.get(obj) == null ? null : field.get(obj)));
                        break;
                    case 1:
                        json.put(field.getName(), (int) (field.get(obj) == null ? 0 : field.get(obj)));
                        break;
                    case 2:
                        json.put(field.getName(), (long) (field.get(obj) == null ? 0 : field.get(obj)));
                        break;
                    case 3:
                        json.put(field.getName(), (float) (field.get(obj) == null ? 0 : field.get(obj)));
                        break;
                    case 4:
                        json.put(field.getName(), (double) (field.get(obj) == null ? 0 : field.get(obj)));
                        break;
                    case 5:
                        json.put(field.getName(), (boolean) (field.get(obj) == null ? false : field.get(obj)));
                        break;
                    case 6:
                    case 7:
                    case 8://JsonArray型
                        json.put(field.getName(), (field.get(obj) == null ? null : field.get(obj)));
                        break;
                    case 9:
                        json.put(field.getName(), new JSONArray((List<?>) field.get(obj)));
                        break;
                    case 10:
                        json.put(field.getName(), new JSONObject((HashMap<?, ?>) field.get(obj)));
                        break;
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } finally {
            return json;
        }
    }

    /**
     * 模拟量转化
     *
     * @return
     */
    public static String formatAttr(String value, int type, Double ratio, Double k, Integer transformer) {
        if (CommonUtil.checkNull(value)) {
            return "0";
        }
        if (type == 0) {
            if (ratio == null) {
                ratio = 1D;
            }
            if (k == null) {
                k = 1D;
            }
            if (transformer == null) {
                transformer = 2;
            }
            Double itemValue = Double.valueOf(value);
            if (transformer == 0) {
                itemValue = (itemValue * k - 4) * ratio * 5 / 4;
                if (itemValue < 0) {
                    itemValue = 0D;
                }
                if (itemValue > 20 * ratio) {
                    itemValue = 20 * ratio;
                }
            } else {
                itemValue = itemValue * k * ratio;
                if (transformer == 1) {
                    if (itemValue < 0) {
                        itemValue = 0D;
                    }
                    if (itemValue > 20 * ratio) {
                        itemValue = 20 * ratio;
                    }
                }
            }
            return formatZeroAndDot(String.format("%.3f", itemValue));
        } else {
            return value;
        }
    }

    /**
     * 控制值转化
     *
     * @return
     */
    public static String formatControlAttr(String value, int type, Double ratio, Double k, Integer transformer) {
        if (CommonUtil.checkNull(value)) {
            return "0";
        }
        if (type == 0) {
            if (ratio == null) {
                ratio = 1D;
            }
            if (k == null) {
                k = 1D;
            }
            if (transformer == null) {
                transformer = 2;
            }
            Double itemValue = Double.valueOf(value);
            if (transformer == 0) {
                itemValue = (4 / 5 * itemValue / ratio + 4) / k;
            } else {
                itemValue = (itemValue / ratio) / k;
            }
            return itemValue + "";
        } else {
            return value;
        }
    }

    /**
     * 使用java正则表达式去掉多余的.与0
     *
     * @return
     */
    public static String formatZeroAndDot(String s) {
        if (s.indexOf(".") > 0) {
            s = s.replaceAll("0+?$", "");//去掉多余的0
            s = s.replaceAll("[.]$", "");//如最后一位是.则去掉
        }
        return s;
    }
}
